package com.yfbao.horizon.utils;


import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.encryption.StandardDecryptionMaterial;
import org.apache.pdfbox.pdmodel.font.PDType1Font;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

public class PDFUtil {

    public static void modifyPdf(String sourcePath, String destPath) throws Exception {
        PdfReader reader = null;
        PdfStamper stamper = null;
        try {
            reader = new PdfReader(sourcePath);

            System.out.println("PDF版本: " + reader.getPdfVersion());
            System.out.println("页数: " + reader.getNumberOfPages());
            System.out.println("是否加密: " + reader.isEncrypted());
            System.out.println("是否被保护: " + reader.isOpenedWithFullPermissions());

            // 检查每一页的大小
            for (int i = 1; i <= reader.getNumberOfPages(); i++) {
                Rectangle rect = reader.getPageSize(i);
                System.out.println("第 " + i + " 页尺寸: " + rect.getWidth() + " x " + rect.getHeight());
            }

            stamper = new PdfStamper(reader, new FileOutputStream(destPath));

            // 获取第一页
            PdfContentByte canvas = stamper.getOverContent(1);
            canvas.beginText();

            // 方案1：使用基本字体（最可靠）
            BaseFont baseFont = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED);

            // 方案2：如果需要中文，使用系统字体（指定完整路径）
            // BaseFont baseFont = BaseFont.createFont("C:/Windows/Fonts/simhei.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);

            canvas.setFontAndSize(baseFont, 20);
            canvas.setRGBColorFill(255, 0, 0); // 红色，便于识别

            // 在多个位置添加测试文本
            canvas.setTextMatrix(50, 700);
            canvas.showText("12313131");

            canvas.setTextMatrix(50, 600);
            canvas.showText("2222fffff");

            canvas.setTextMatrix(50, 500);
            canvas.showText("TEST POSITION 3");

            canvas.endText();

            stamper.close();
            reader.close();
        }catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 确保正确关闭资源
            if (stamper != null) {
                try {
                    stamper.close(); // 这个调用才会真正保存修改！
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (reader != null) {
                reader.close();
            }
        }

    }


    public static void addWatermark(String sourcePath, String destPath, String watermarkText)
            throws IOException, DocumentException {

        PdfReader reader = new PdfReader(sourcePath);
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(destPath));

        // 为每一页添加水印
        for (int i = 1; i <= reader.getNumberOfPages(); i++) {
            PdfContentByte over = stamper.getOverContent(i);
            over.beginText();
            BaseFont baseFont = BaseFont.createFont(BaseFont.HELVETICA,
                    BaseFont.WINANSI, BaseFont.EMBEDDED);
            over.setFontAndSize(baseFont, 40);
            over.setRGBColorFill(200, 200, 200); // 浅灰色
            // 设置透明度
            PdfGState gs = new PdfGState();
            gs.setFillOpacity(0.3f);
            over.setGState(gs);

            // 在页面中心添加水印文本
            over.showTextAligned(Element.ALIGN_CENTER, watermarkText,
                    300, 400, 45); // 45度倾斜

            over.endText();
        }

        stamper.close();
        reader.close();
    }

//    public static boolean decryptWithPdfBox(String sourcePath, String destPath, String password) {
//        try {
//            // 加载加密的PDF
//            PDDocument document = PDDocument.load(new File(sourcePath), password);
//
//            if (document.isEncrypted()) {
//                // 解密文档
//                StandardDecryptionMaterial sdm = new StandardDecryptionMaterial(password);
//                document.openProtection(sdm);
//            }
//
//            // 现在可以修改
//            PDPage page = document.getPage(0);
//            PDPageContentStream contentStream = new PDPageContentStream(
//                    document, page, PDPageContentStream.AppendMode.APPEND, true);
//
//            contentStream.beginText();
//            contentStream.setFont(PDType1Font.HELVETICA_BOLD, 12);
//            contentStream.newLineAtOffset(100, 700);
//            contentStream.showText("使用PDFBox解密的文本");
//            contentStream.endText();
//            contentStream.close();
//
//            // 保存为无保护PDF
//            document.setAllSecurityToBeRemoved(true);
//            document.save(destPath);
//            document.close();
//
//            return true;
//
//        } catch (Exception e) {
//            System.err.println("PDFBox解密失败: " + e.getMessage());
//            return false;
//        }
//    }


    /**
     * 合法地重新创建类似内容
     */
    public static void recreatePdfContent(String protectedPdfPath, String newPdfPath) {
        try {
            // 1. 如果允许打印，可以打印后扫描
            // 2. 手动重新输入公开信息
            // 3. 使用OCR提取允许公开的内容
            // 4. 重新设计和生成PDF

            Document document = new Document();
            PdfWriter.getInstance(document, new FileOutputStream(newPdfPath));
            document.open();

            // 添加合法获取的内容
            document.add(new Paragraph("合法重新创建的内容"));
            document.add(new Paragraph("基于公开信息重新整理"));

            document.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static boolean checkPdf(String pdfPath) {
        try {
            PdfReader reader = new PdfReader(pdfPath);

            System.out.println("=== PDF安全分析 ===");
            System.out.println("加密算法: " + getEncryptionAlgorithm(reader));
            System.out.println("密钥长度: " + getKeyLength(reader));
            System.out.println("PDF版本: " + reader.getPdfVersion());

            System.out.println("PDF版本: " + reader.getPdfVersion());
            System.out.println("页数: " + reader.getNumberOfPages());
            System.out.println("是否加密: " + reader.isEncrypted());
            System.out.println("是否被保护: " + reader.isOpenedWithFullPermissions());

            // 检查每一页的大小
            for (int i = 1; i <= reader.getNumberOfPages(); i++) {
                Rectangle rect = reader.getPageSize(i);
                System.out.println("第 " + i + " 页尺寸: " + rect.getWidth() + " x " + rect.getHeight());
            }

            reader.close();
            return reader.isEncrypted() || reader.isOpenedWithFullPermissions();
        } catch (Exception e) {
            System.out.println("需要密码才能分析");
        }
        return false;
    }

    private static String getEncryptionAlgorithm(PdfReader reader) {
        // 分析加密算法类型
        return "AES-128/256 (现代加密)"; // 或 "RC4 (较老加密)"
    }

    private static int getKeyLength(PdfReader reader) {
        // 获取密钥长度
        return 128; // 或40, 256等
    }


    public static String getOpenPdf(String srcPath){
        if(checkPdf(srcPath)){
            String openPdfPath = "D:\\下载\\opened.pdf";
            recreatePdfContent(srcPath, openPdfPath);
            return openPdfPath;
        }
        return srcPath;
    }

    public static String testProtectedPdf(String sourcePath) {
//        String sourcePath = "protected.pdf";
        String destPath = "D:\\下载\\unprotected.pdf";

        // 方法1：尝试已知密码
        boolean success = processProtectedPdf(sourcePath, destPath, "owner123");

        if (!success) {
            // 方法2：尝试常见密码
            List<String> commonPasswords = Arrays.asList("", "123456", "password", "owner", "1234");
            String foundPassword = bruteForceDecrypt(sourcePath, commonPasswords);

            if (foundPassword != null) {
                System.out.println("找到密码: " + foundPassword);
                processProtectedPdf(sourcePath, destPath, foundPassword);
            } else {
                System.out.println("无法解密PDF，可能需要专业工具或所有者密码");
            }
        }
        return destPath;
    }

    public static void main(String[] args) {
//        String srcFile ="D:\\下载\\S9558202511032307612-885699688464-78593-1762173818124.pdf";
        String srcFile ="D:\\下载\\bbb.pdf";
        String openPdf = getOpenPdf(srcFile);

        System.out.println("可打开的PDF路径: " + openPdf);
        checkPdf(openPdf);

//        String decryPDF = testProtectedPdf(srcFile);
//        checkPdf(decryPDF);


//        srcFile=decryPDF;
        String destFile ="D:\\下载\\modified.pdf";
        try {
            modifyPdf(srcFile, destFile);
            System.out.println("PDF 修改完成！");
        } catch (Exception e) {
            System.out.println("PDF 修改失败：" + e.getMessage());
            throw new RuntimeException(e);
        }

//        String destFile2 ="D:\\下载\\modified2.pdf";
//        try {
//            addWatermark(srcFile, destFile2, "机密文件");
//            System.out.println("PDF 添加水印完成！");
//        }catch (Exception e){
//            System.out.println("添加水印失败：" + e.getMessage());
//            throw new RuntimeException(e);
//        }
    }











    public static boolean processProtectedPdf(String sourcePath, String destPath, String password) {
        try {
            // 首先尝试直接打开（可能不需要密码）
            PdfReader reader;
            try {
                reader = new PdfReader(sourcePath);
            } catch (Exception e) {
                // 如果需要密码，使用密码打开
                if (password != null && !password.trim().isEmpty()) {
                    reader = new PdfReader(sourcePath, password.getBytes());
                } else {
                    // 尝试空密码
                    reader = new PdfReader(sourcePath, "".getBytes());
                }
            }

            // 检查权限
            if (!reader.isOpenedWithFullPermissions()) {
                System.out.println("警告：没有完整权限，某些操作可能受限");
            }

            // 进行修改
            boolean success = modifyPdfContent(reader, destPath);
            reader.close();

            return success;

        } catch (Exception e) {
            System.err.println("处理保护PDF失败: " + e.getMessage());
            return false;
        }
    }

    private static boolean modifyPdfContent(PdfReader reader, String destPath) {
        try {
            PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(destPath));

            // 如果可能，移除或减少保护
            try {
                stamper.setEncryption(null, null,
                        PdfWriter.ALLOW_PRINTING | PdfWriter.ALLOW_MODIFY_CONTENTS |
                                PdfWriter.ALLOW_COPY | PdfWriter.ALLOW_SCREENREADERS,
                        PdfWriter.STANDARD_ENCRYPTION_128);
            } catch (Exception e) {
                System.out.println("无法修改加密设置，但可以继续添加内容");
            }

            // 添加内容
            PdfContentByte canvas = stamper.getOverContent(1);
            canvas.beginText();
            BaseFont baseFont = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED);
            canvas.setFontAndSize(baseFont, 12);
            canvas.setTextMatrix(100, 700);
            canvas.showText("成功添加到受保护PDF的内容");
            canvas.endText();

            stamper.close();
            return true;

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 批量尝试解密
     */
    public static String bruteForceDecrypt(String sourcePath,List<String> commonPasswords) {
//        List<String> commonPasswords = Arrays.asList("", "123456", "password", "owner", "1234");
        for (String password : commonPasswords) {
            try {
                PdfReader reader = new PdfReader(sourcePath, password.getBytes());
                if (reader.isOpenedWithFullPermissions()) {
                    reader.close();
                    return password;
                }
                reader.close();
            } catch (Exception e) {
                // 继续尝试
            }
        }
        return null;
    }
}
